package com.yvon.maple.utils;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import lombok.experimental.UtilityClass;
import org.springframework.beans.BeanUtils;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.NonNull;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;;

/**
 * 类型转换器
 *
 * @author : Yvon
 * @since : 2021-07-06
 */
@UtilityClass
public class DataConverter {

    /**
     * conversionService
     */
 //   private static ConversionService conversionService;

    /**
     * Set conversion service.
     *
     * @param conversionService the conversion service
     * @return
     * @author : Yvon / 2021-07-06
     */
//    public static void setConversionService(ConversionService conversionService){
//        DataConverter.conversionService = conversionService;
//    }

    /**
     * Copy t.
     *
     * @param source      the source
     * @param targetClass the target class
     * @return {@link T }
     * @author : Yvon / 2021-07-06
     */
    public static <T, S> T copy(@NonNull S source, @NonNull Class<T> targetClass){
        try {
            T target = targetClass.newInstance();
            BeanUtils.copyProperties(source, target);
            return target;
        } catch (Exception e) {
            throw new ConversionFailedException(TypeDescriptor.valueOf(source.getClass()), TypeDescriptor.valueOf(targetClass), source, e);
        }
    }

    /**
     * Convert t.
     *
     * @param source      the source
     * @param targetClass the target class
     * @return {@link T }
     * @author : Yvon / 2021-07-06
     */
    public static <T, S> T convert(S source, Class<T> targetClass){
        if (Objects.isNull(source)) {
            return null;
        }
//        if (conversionService.canConvert(source.getClass(), targetClass)){
//            return conversionService.convert(source, targetClass);
//        } else {
            return copy(source, targetClass);
 //       }
    }

    /**
     * Convert list.
     *
     * @param sources     the sources
     * @param targetClass the target class
     * @return {@link List<T> }
     * @author : Yvon / 2021-07-06
     */
    public static <T, S> List<T> convert(Collection<S> sources, Class<T> targetClass){
        if (CollUtil.isNotEmpty(sources)){
            return sources.stream()
                    .map(source -> convert(source, targetClass))
                    .collect(Collectors.toList());
        }

        return Lists.newArrayList();

    }
}